// 修复版电表数据收集脚本
// 解决历史数据过度清理导致滚动窗口计算失败的问题

// 转换系数配置
const VALUE_CONVERSION_FACTOR = 1;

// 数据保留配置 - 只保留当天数据，聚合层负责历史数据管理
const DATA_RETENTION_CONFIG = {
    // 采集层只保留当天数据
    HISTORY_RETENTION_DAYS: 1,  // 只保留当天数据
    // 单个测点最大历史记录数
    MAX_HISTORY_RECORDS: 1000
};

// 获取测点配置
const validPointIds = new Set();
const electricPoints = global.get('_ELECTRIC_POINTS_');

// 调试函数
function debugLog(msg, data) {
    if (data === undefined) {
        node.warn(`DEBUG - ${msg}`);
    } else {
        node.warn(`DEBUG - ${msg}: ${JSON.stringify(data, null, 2)}`);
    }
}

// 添加调试日志
debugLog('Loaded Electric Points Configuration', electricPoints);

if (electricPoints) {
    Object.keys(electricPoints).forEach(pointId => {
        validPointIds.add(pointId);
    });
    debugLog('Initialized Valid Point IDs', Array.from(validPointIds));
} else {
    node.error("No electric points configuration found in global context - collection cannot proceed");
    return msg;
}

// Add validation for empty set
if (validPointIds.size === 0) {
    node.error("No valid point IDs found - check if _ELECTRIC_POINTS_ global variable is properly initialized");
    return msg;
}

// 初始化统计结构
function initializeStatistics() {
    // 获取现有统计数据
    const existingStats = global.get('_ELECTRIC_STATISTICS_');
    
    // 如果已存在统计数据，保留它
    if (existingStats) {
        debugLog('Using existing statistics structure', {
            hasPoints: Object.keys(existingStats.byMeasurementPoint || {}).length,
            lastUpdated: existingStats.lastUpdated
        });
        return existingStats;
    }
    
    // 只有在不存在时才创建新的统计结构
    const newStats = {
        byMeasurementPoint: {},
        byTimeDimension: {
            daily: {},
            weekly: {},
            monthly: {},
            yearly: {}
        },
        lastUpdated: null
    };
    
    debugLog('Created new statistics structure', null);
    return newStats;
}

// 初始化测点统计
function initializePointStats() {
    return {
        history: [],
        stats: { min: Infinity, max: -Infinity, sum: 0, count: 0, average: 0 }
    };
}

// 智能历史数据清理
function cleanHistoryData(history, currentDate) {
    if (!Array.isArray(history) || history.length === 0) {
        return [];
    }
    
    // 计算保留截止日期
    const retentionDate = new Date(currentDate);
    retentionDate.setDate(retentionDate.getDate() - DATA_RETENTION_CONFIG.HISTORY_RETENTION_DAYS);
    const retentionDateString = retentionDate.toISOString().slice(0, 10);
    
    // 过滤有效的历史数据
    let cleanedHistory = history
        .filter(entry => {
            // 基本数据验证
            if (!entry || !entry.timestamp || typeof entry.value !== 'number') {
                return false;
            }
            
            // 时间范围验证
            const entryDate = entry.timestamp.slice(0, 10);
            return entryDate >= retentionDateString;
        })
        .sort((a, b) => new Date(a.timestamp).getTime() - new Date(b.timestamp).getTime());
    
    // 如果记录数超过限制，保留最新的记录
    if (cleanedHistory.length > DATA_RETENTION_CONFIG.MAX_HISTORY_RECORDS) {
        cleanedHistory = cleanedHistory.slice(-DATA_RETENTION_CONFIG.MAX_HISTORY_RECORDS);
    }
    
    return cleanedHistory;
}

// 获取当前时间 - 每次执行时都重新获取
function getCurrentTimestamp() {
    return new Date();
}

function getCurrentDateString() {
    return getCurrentTimestamp().toISOString().slice(0, 10);
}

try {
    // 获取原始数据
    const rawDataPool = global.get('_DATA_POOL_');
    
    // 验证数据结构
    if (!rawDataPool || !rawDataPool.props) {
        node.error("Invalid or empty data pool");
        debugLog('Data Pool Status', {
            hasDataPool: !!rawDataPool,
            hasProps: rawDataPool ? !!rawDataPool.props : false
        });
        return msg;
    }

    debugLog('Raw Props', rawDataPool.props);
    debugLog('Available Point IDs in Data', Object.keys(rawDataPool.props));

    // 获取或初始化统计结构
    let statistics = initializeStatistics();

    // 创建一个安全的数据副本，只包含配置中的测点
    const validData = {};
    const skippedPoints = {};
    
    Object.keys(rawDataPool.props).forEach(pointId => {
        if (validPointIds.has(pointId)) {
            const value = rawDataPool.props[pointId];
            // 确保值不是undefined或null
            if (value !== undefined && value !== null) {
                // 如果值是对象（比如bits结构），获取orig值
                if (typeof value === 'object' && value.hasOwnProperty('orig')) {
                    validData[pointId] = value.orig;
                } else {
                    validData[pointId] = value;
                }
            }
        } else {
            skippedPoints[pointId] = rawDataPool.props[pointId];
        }
    });

    debugLog('Points Being Processed', {
        validPoints: Object.keys(validData),
        skippedPoints: Object.keys(skippedPoints),
        configuredPoints: Array.from(validPointIds),
        currentDate: getCurrentDateString()
    });

    // 如果没有有效数据，直接返回
    if (Object.keys(validData).length === 0) {
        node.warn("No valid electric points data found - check if point IDs match between data and configuration");
        return msg;
    }

    // 实时数据处理
    Object.entries(validData).forEach(([pointId, value]) => {
        try {
            // 确保测点ID有效
            if (!validPointIds.has(pointId)) {
                debugLog(`Point ${pointId} not in valid points list`, null);
                return;
            }

            // 转换为数值并验证
            let rawValue = Number(value);
            if (isNaN(rawValue)) {
                debugLog(`Invalid numeric value for point ${pointId}`, value);
                return;
            }

            // 转换为真实值
            const latestValue = Number((rawValue / VALUE_CONVERSION_FACTOR).toFixed(2));

            // 初始化或获取测点数据
            if (!statistics.byMeasurementPoint[pointId]) {
                statistics.byMeasurementPoint[pointId] = initializePointStats();
            }

            const pointStats = statistics.byMeasurementPoint[pointId];

            // 确保history数组存在
            if (!Array.isArray(pointStats.history)) {
                pointStats.history = [];
            }

            // 智能清理历史数据 - 保留足够的数据支持滚动窗口计算
            const currentTimestamp = getCurrentTimestamp();
            pointStats.history = cleanHistoryData(pointStats.history, currentTimestamp);
            
            // 检查是否已有相同时间戳的记录（避免重复添加）
            const currentTimestampString = currentTimestamp.toISOString();
            const existingIndex = pointStats.history.findIndex(entry => 
                entry.timestamp === currentTimestampString
            );
            
            if (existingIndex >= 0) {
                // 更新现有记录
                pointStats.history[existingIndex].value = latestValue;
                debugLog(`Updated existing record for point ${pointId}`, {
                    timestamp: currentTimestampString,
                    value: latestValue
                });
            } else {
                // 添加新数据
                pointStats.history.push({
                    value: latestValue,
                    timestamp: currentTimestampString
                });
                debugLog(`Added new record for point ${pointId}`, {
                    timestamp: currentTimestampString,
                    value: latestValue,
                    historyLength: pointStats.history.length
                });
            }

            // 重新计算统计指标（基于最新可用数据）
            const currentDateString = getCurrentDateString();
            
            // 优先使用当天数据，如果没有则使用最新可用数据
            let targetHistory = pointStats.history.filter(entry => 
                entry.timestamp.startsWith(currentDateString)
            );
            
            // 如果当天没有数据，使用最新的数据（可能是昨天的）
            if (targetHistory.length === 0 && pointStats.history.length > 0) {
                // 按时间排序，获取最新的数据
                const sortedHistory = [...pointStats.history].sort((a, b) => 
                    new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime()
                );
                
                // 获取最新数据的日期
                const latestDate = sortedHistory[0].timestamp.slice(0, 10);
                targetHistory = pointStats.history.filter(entry => 
                    entry.timestamp.startsWith(latestDate)
                );
                
                debugLog(`No current day data for ${pointId}, using latest available data from ${latestDate}`, {
                    currentDate: currentDateString,
                    latestDataDate: latestDate,
                    recordsCount: targetHistory.length
                });
            }
            
            if (targetHistory.length > 0) {
                const targetValues = targetHistory.map(entry => entry.value);
                pointStats.stats.count = targetValues.length;
                pointStats.stats.sum = Number(targetValues.reduce((sum, val) => sum + val, 0).toFixed(2));
                pointStats.stats.average = Number((pointStats.stats.sum / pointStats.stats.count).toFixed(2));
                pointStats.stats.min = Number(Math.min(...targetValues).toFixed(2));
                pointStats.stats.max = Number(Math.max(...targetValues).toFixed(2));
            }

        } catch (pointError) {
            node.warn(`Error processing point ${pointId}: ${pointError.message}`);
        }
    });

    // 保存结果
    statistics.lastUpdated = getCurrentTimestamp().toISOString();
    global.set('_ELECTRIC_STATISTICS_', statistics);
    
    // 生成详细的调试报告
    const finalCurrentDateString = getCurrentDateString();
    const debugReport = {
        pointsCount: Object.keys(statistics.byMeasurementPoint).length,
        timestamp: statistics.lastUpdated,
        currentDate: finalCurrentDateString,
        samplePoints: {}
    };
    
    // 添加样本点的历史数据信息
    Object.keys(statistics.byMeasurementPoint).slice(0, 3).forEach(pointId => {
        const pointData = statistics.byMeasurementPoint[pointId];
        debugReport.samplePoints[pointId] = {
            historyLength: pointData.history.length,
            oldestRecord: pointData.history.length > 0 ? pointData.history[0].timestamp.slice(0, 10) : null,
            newestRecord: pointData.history.length > 0 ? pointData.history[pointData.history.length - 1].timestamp.slice(0, 10) : null,
            todayRecords: pointData.history.filter(entry => entry.timestamp.startsWith(finalCurrentDateString)).length
        };
    });
    
    debugLog('Final Statistics Status', debugReport);

} catch (error) {
    node.error("Error processing data: " + error.message);
    node.warn(error.stack);
}

return msg;